home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 16
/
Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso
/
Aminet
/
misc
/
emu
/
AmigaVGB.lha
/
AmigaVGB
/
Unix.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-05
|
10KB
|
322 lines
/** VGB: portable GameBoy emulator ***************************/
/** **/
/** Unix.c **/
/** **/
/** This file contains Unix/X-dependent subroutines and **/
/** drivers. **/
/** **/
/** Copyright (C) Marat Fayzullin 1994,1995,1996 **/
/** Elan Feingold 1995 **/
/** You are not allowed to distribute this software **/
/** commercially. Please, notify me, if you make any **/
/** changes to this file. **/
/*************************************************************/
#define USE_XPAL /* We are using XPal[] to determine colors */
/** Standard Unix/X #includes ********************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include "GB.h"
/** MIT Shared Memory Extension for X ************************/
#ifdef MITSHM
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
XShmSegmentInfo SHMInfo;
int UseSHM=1;
#endif
/** Various X-related variables ******************************/
Display *Dsp;
Window Wnd;
Colormap DefaultCMap;
XImage *Img;
GC DefaultGC;
unsigned long White,Black;
/** Various variables and short functions ********************/
#define WIDTH 176 /* Width (>=176, must be divisible by 8) */
#define HEIGHT 144 /* Height (>=144) */
char *Title = "Virtual GameBoy Unix/X 0.7";
int SaveCPU = 1;
byte *XBuf,*ZBuf,XPal[12];
char *ColorNames[12] =
{
"white","#989898","#585858","black",
"white","#989898","#585858","black",
"white","#989898","#585858","black"
};
void OnBreak(int Arg) { CPURunning=0; }
/** InitMachine **********************************************/
/** Allocate resources needed by Unix/X-dependent code. **/
/*************************************************************/
int InitMachine()
{
Screen *Scr;
XEvent E;
XGCValues values;
XColor Color,C;
int J;
if(Verbose)
printf("Initializing Unix/X drivers:\n Opening display...");
Dsp=XOpenDisplay(NULL);
if(!Dsp) { if(Verbose) printf("FAILED\n");return(0); }
Scr=DefaultScreenOfDisplay(Dsp);
White=WhitePixelOfScreen(Scr);
Black=BlackPixelOfScreen(Scr);
DefaultGC=DefaultGCOfScreen(Scr);
DefaultCMap=DefaultColormapOfScreen(Scr);
if(Verbose) printf("OK\n Opening window...");
Wnd=
XCreateSimpleWindow
(Dsp,RootWindowOfScreen(Scr),0,0,160,144,0,White,Black);
if(!Wnd) { if(Verbose) printf("FAILED\n");return(0); }
{
XSizeHints Hints;
XWMHints WMHints;
Hints.flags=PSize|PMinSize|PMaxSize;
Hints.min_width=Hints.max_width=Hints.base_width=160;
Hints.min_height=Hints.max_height=Hints.base_height=144;
WMHints.input=True;WMHints.flags=InputHint;
XSetWMHints(Dsp,Wnd,&WMHints);
XSetWMNormalHints(Dsp,Wnd,&Hints);
XStoreName(Dsp,Wnd,Title);
}
XSelectInput
(Dsp,Wnd,FocusChangeMask|ExposureMask|KeyPressMask|KeyReleaseMask);
XMapRaised(Dsp,Wnd);
XClearWindow(Dsp,Wnd);
XAutoRepeatOff(Dsp);
XWindowEvent(Dsp,Wnd,ExposureMask,&E);
if(Verbose) printf("OK\n Allocating Z-buffer...");
if(!(ZBuf=malloc(2*WIDTH*HEIGHT/8))) return(0);
#ifdef MITSHM
if(UseSHM)
{
if(Verbose) printf("OK\n Using shared memory:\n Creating image...");
Img=
XShmCreateImage
(Dsp,DefaultVisualOfScreen(Scr),8,ZPixmap,NULL,&SHMInfo,WIDTH,HEIGHT);
if(!Img) { if(Verbose) printf("FAILED\n");return(0); }
if(Verbose) printf("OK\n Getting SHM info...");
SHMInfo.shmid=
shmget(IPC_PRIVATE,Img->bytes_per_line*Img->height,IPC_CREAT|0777);
if(SHMInfo.shmid<0) { if(Verbose) printf("FAILED\n");return(0); }
if(Verbose) printf("OK\n Allocating SHM...");
XBuf=(byte *)(Img->data=SHMInfo.shmaddr=shmat(SHMInfo.shmid,0,0));
if(!XBuf) { if(Verbose) printf("FAILED\n");return(0); }
SHMInfo.readOnly=False;
if(Verbose) printf("OK\n Attaching SHM...");
if(!XShmAttach(Dsp,&SHMInfo))
{ if(Verbose) printf("FAILED\n");return(0); }
}
else
#endif
{
if(Verbose) printf("OK\n Allocating screen buffer...");
XBuf=(byte *)malloc(sizeof(byte)*HEIGHT*WIDTH);
if(!XBuf) { if(Verbose) printf("FAILED\n");return(0); }
if(Verbose) printf("OK\n Creating image...");
Img=
XCreateImage
(Dsp,DefaultVisualOfScreen(Scr),8,ZPixmap,0,XBuf,WIDTH,HEIGHT,8,0);
if(!Img) { if(Verbose) printf("FAILED\n");return(0); }
}
if(Verbose) puts("OK");
for(J=0;J<12;J++)
XPal[J]=XAllocNamedColor(Dsp,DefaultCMap,ColorNames[J],&Color,&C)?
Color.pixel : J&2? White:Black;
signal(SIGHUP,OnBreak);signal(SIGINT,OnBreak);
signal(SIGQUIT,OnBreak);signal(SIGTERM,OnBreak);
return(1);
}
/** TrashMachine *********************************************/
/** Deallocate all resources taken by InitMachine(). **/
/*************************************************************/
void TrashMachine()
{
if(Verbose) printf("Shutting down...\n");
if(Dsp&&Wnd)
{
#ifdef MITSHM
if(UseSHM)
{
XShmDetach(Dsp,&SHMInfo);
if(SHMInfo.shmaddr) shmdt(SHMInfo.shmaddr);
if(SHMInfo.shmid>=0) shmctl(SHMInfo.shmid,IPC_RMID,0);
}
else
#endif MITSHM
if(Img) XDestroyImage(Img);
}
if(ZBuf) free(ZBuf);
if(Dsp) { XAutoRepeatOn(Dsp);XCloseDisplay(Dsp); }
}
/** PutImage *************************************************/
/** Put an image on the screen. **/
/*************************************************************/
void PutImage()
{
#ifdef MITSHM
if(UseSHM)
XShmPutImage(Dsp,Wnd,DefaultGC,Img,(WIDTH-160)/2,0,0,0,160,144,False);
else
#endif
XPutImage(Dsp,Wnd,DefaultGC,Img,(WIDTH-160)/2,0,0,0,160,144);
XFlush(Dsp);
}
/** Joystick *************************************************/
/** Return the current joystick state. **/
/*************************************************************/
byte Joystick(void)
{
static byte JoyState = 0xFF;
XEvent E;
word J;
if(XCheckWindowEvent(Dsp,Wnd,KeyPressMask|KeyReleaseMask,&E))
{
J=XLookupKeysym((XKeyEvent *)&E,0);
if(E.type==KeyPress)
switch(J)
{
case XK_F12:
case XK_Escape: CPURunning=0;break;
#ifdef DEBUG
case XK_F1: Trace=!Trace;break;
case XK_F2: puts("\033[H\033[2J*** REGISTERS: ***");
for(J=0xFF40;J<0xFF50;J++)
printf("(%Xh) = %Xh\n",J,RAM[J]);
printf("ISWITCH = %Xh\n",ISWITCH);
break;
case XK_F3: puts("\033[H\033[2J*** SPRITES: ***");
for(J=0xFE9C;J<0xFE9C+4*40;J+=4)
printf
(
"SPRITE %d: %d,%d Pat %d Attr %d\n",
(J-0xFE9C)/4,RAM[J+1],RAM[J],RAM[J+2],RAM[J+3]
);
break;
#endif
case XK_Return: JoyState&=0x7F;break;
case XK_Tab: JoyState&=0xBF;break;
case XK_Down: JoyState&=0xF7;break;
case XK_Up: JoyState&=0xFB;break;
case XK_Left: JoyState&=0xFD;break;
case XK_Right: JoyState&=0xFE;break;
case XK_z: case XK_x: case XK_c: case XK_v:
case XK_b: case XK_n: case XK_m:
case XK_Z: case XK_X: case XK_C: case XK_V:
case XK_B: case XK_N: case XK_M:
case XK_Alt_L: JoyState&=0xDF;break;
case XK_a: case XK_s: case XK_d: case XK_f:
case XK_g: case XK_h: case XK_j:
case XK_A: case XK_S: case XK_D: case XK_F:
case XK_G: case XK_H: case XK_J:
case XK_space: JoyState&=0xEF;break;
}
else
switch(J)
{
case XK_Return: JoyState|=0x80;break;
case XK_Tab: JoyState|=0x40;break;
case XK_Down: JoyState|=0x08;break;
case XK_Up: JoyState|=0x04;break;
case XK_Left: JoyState|=0x02;break;
case XK_Right: JoyState|=0x01;break;
case XK_z: case XK_x: case XK_c: case XK_v:
case XK_b: case XK_n: case XK_m:
case XK_Z: case XK_X: case XK_C: case XK_V:
case XK_B: case XK_N: case XK_M:
case XK_Alt_L: JoyState|=0x20;break;
case XK_a: case XK_s: case XK_d: case XK_f:
case XK_g: case XK_h: case XK_j:
case XK_A: case XK_S: case XK_D: case XK_F:
case XK_G: case XK_H: case XK_J:
case XK_space: JoyState|=0x10;break;
}
}
for(J=0;XCheckWindowEvent(Dsp,Wnd,FocusChangeMask,&E);)
J=(E.type==FocusOut);
if(SaveCPU&&J)
{
XAutoRepeatOn(Dsp);
while(!XCheckWindowEvent(Dsp,Wnd,FocusChangeMask,&E)&&CPURunning)
{
if(XCheckWindowEvent(Dsp,Wnd,ExposureMask,&E)) PutImage();
XPeekEvent(Dsp,&E);
}
XAutoRepeatOff(Dsp);
}
return(JoyState);
}
/*** SIOSend ****************************************************/
/*** Send a byte onto the serial line. ***/
/****************************************************************/
byte SIOSend(register byte V) { return(0); }
/*** SIOReceive *************************************************/
/*** Receive a byte from the serial line. Returns 1 on ***/
/*** success, 0 otherwise. ***/
/****************************************************************/
byte SIOReceive(register byte *V) { return(0); }
/****************************************************************/
/*** Write value into sound chip register (Reg #0 at FF10h). ***/
/****************************************************************/
void Sound(byte R,byte V) { return; }
/** Common.h ****************************************************/
/** Parts of the drivers common for Unix/X and MSDOS. **/
/****************************************************************/
#include "Common.h"